﻿// <copyright file="MainForm.cs" company="Horiba Medical">
//     Copyright (c) Horiba Medical. All rights reserved.
// </copyright>
// <summary>
//     Main form description and functions.
// </summary>

namespace DoxyOutParser.Forms
{
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.ComponentModel;
	using System.IO;
	using System.Windows.Forms;
	using DoxyOutParser.CodeCheck;
	using DoxyOutParser.Launcher;
	using DoxyOutParser.Parser;
	using DoxyOutParser.WorkingSet;

	/// <summary>
	/// Provides the main GUI for the DoxyOutParser application.
	/// </summary>
	public partial class MainForm : Form
	{
		/// <summary>
		/// List of warnings and errors generated by Doxygen.
		/// </summary>
		private OutputEntryCollection doxygenEntryList;

		/// <summary>
		/// List of warnings and errors generated by Splint.
		/// </summary>
		private OutputEntryCollection splintEntryList;

		/// <summary>
		/// Initializes a new instance of the MainForm class.
		/// </summary>
		public MainForm()
		{
			this.InitializeComponent();

			this.Setup();
		}

		/// <summary>
		/// Populate combo boxes with project files found in the project working directory provided.
		/// </summary>
		/// <param name="box">The combo box to populate.</param>
		/// <param name="workingDir">The project working directory.</param>
		private static void PopulateComboBoxWithProjectFiles(ToolStripComboBox box, string workingDir)
		{
			List<WorkSet> projects = new List<WorkSet>();

			try
			{
				ProgressForm progress = new ProgressForm();

				progress.SetProgressStep(14);
				progress.Text = "Searching for projects ...";

				progress.Show();

				// Empty & the box to avoid duplicating entries
				progress.SetLabel("Cleaning a bit ...");
				box.Items.Clear();
				progress.UpdateProgression();

				// Get the uv2 project files
				progress.SetLabel("Searching for UV2 projects ...");
				List<string> uv2ProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDir, "*.uv2");
				progress.UpdateProgression();
				progress.SetLabel("Parsing UV2 projects ...");
				foreach (string projectFile in uv2ProjFilesList)
				{
					projects.Add(new WorkSet(
						projectFile,
						new UV2IncludeDirectoriesParser(projectFile).GetIncludeDirectoriesTable(),
						new UV2SourceFilesParser(projectFile).SourceFilesList,
						new UV2ProjectDefinesParser(projectFile).GetProjectDefinesTable()));
				}

				progress.UpdateProgression();

				// Get the uv4 project files
				progress.SetLabel("Searching for UV4 projects ...");
				List<string> uv4ProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDir, "*.uvproj");
				progress.UpdateProgression();
				progress.SetLabel("Parsing UV4 projects ...");
				foreach (string projectFile in uv4ProjFilesList)
				{
					projects.Add(new WorkSet(
						projectFile,
						new UV4IncludeDirectoriesParser(projectFile).GetIncludeDirectoriesTable(),
						new UV4SourceFilesParser(projectFile).SourceFilesList,
						new UV4ProjectDefinesParser(projectFile).GetProjectDefinesTable()));
				}

				progress.UpdateProgression();

				// Get the TI project files
				progress.SetLabel("Searching for TI projects ...");
				List<string> tiProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDir, "*.pjt");
				progress.UpdateProgression();
				progress.SetLabel("Parsing TI projects ...");
				foreach (string projectFile in tiProjFilesList)
				{
					projects.Add(new WorkSet(
						projectFile,
						new TIIncludeDirectoriesParser(projectFile).GetIncludeDirectoriesTable(),
						new TISourceFilesParser(projectFile).SourceFilesList,
						new TIProjectDefinesParser(projectFile).GetProjectDefinesTable()));
				}

				// Get the BF project files
				progress.SetLabel("Searching for BF projects ...");
				List<string> bfProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDir, "*.dpj");
				progress.UpdateProgression();
				progress.SetLabel("Parsing BF projects ...");
				foreach (string projectFile in bfProjFilesList)
				{
					projects.Add(new WorkSet(
						projectFile,
						new BFIncludeDirectoriesParser(projectFile).GetIncludeDirectoriesTable(),
						new BFSourceFilesParser(projectFile).SourceFilesList,
						new BFProjectDefinesParser(projectFile).GetProjectDefinesTable()));
				}
				progress.UpdateProgression();

				// Refresh Workset list for splint & codecheck combo boxes
				progress.SetLabel("Refreshing project list ...");
				foreach (WorkSet set in projects)
				{
					box.Items.Add(set);
				}

				progress.UpdateProgression();
				progress.SetLabel("Done!");
				progress.Dispose();
			}
			catch
			{
				throw;
			}
		}

		/// <summary>
		/// Setup the GUI by reading the user settings and initiliazing graphical elements to the required values.
		/// </summary>
		private void Setup()
		{
			this.browseBoxDoxygen.Text = user.Default.uKernelDir.ToString();
			if (user.Default.doxygenVersion.ToString().Equals("Cygwin"))
			{
				// enable cygwin control
				this.textBoxDoxCygwinBin.ReadOnly = false;
				this.buttonDoxyBinCygwinBrowse.Enabled = true;

				// disable win32 control
				this.textBoxDoxWin32Bin.ReadOnly = true;
				this.buttonDoxyBinWin32Browse.Enabled = false;
				this.radioButtonDoxCygwin.Checked = true;
			}
			else if (user.Default.doxygenVersion.ToString().Equals("Win32"))
			{
				// disable cygwin control
				this.textBoxDoxCygwinBin.ReadOnly = true;
				this.buttonDoxyBinCygwinBrowse.Enabled = false;

				// enable win32 control
				this.textBoxDoxWin32Bin.ReadOnly = false;
				this.buttonDoxyBinWin32Browse.Enabled = true;
				this.radioButtonDoxWin32.Checked = true;
			}

			if (user.Default.editor.ToString().Equals("TextPad"))
			{
				this.radioButtonTextpad.Checked = true;
			}
			else if (user.Default.editor.ToString().Equals("Notepad++"))
			{
				this.radioButtonNotepadPP.Checked = true;
			}
			else if (user.Default.editor.ToString().Equals("SourceInsight3"))
			{
				this.radioButtonSourceInsight.Checked = true;
			}

			this.splintToolStripTextBoxBrowse.Text = user.Default.splintWorkingDir;
			string splintWorkingDirectory = this.splintToolStripTextBoxBrowse.Text;

			PopulateComboBoxWithProjectFiles(this.splintToolStripComboBox, splintWorkingDirectory);
		}

		#region Configuration

		/// <summary>
		/// Action taken when clicking on the Win32 Doxygen version radio button.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void RadioButtonDoxWin32_Click(object sender, EventArgs e)
		{
			// disable cygwin control
			this.textBoxDoxCygwinBin.ReadOnly = true;
			this.buttonDoxyBinCygwinBrowse.Enabled = false;

			// enable win32 control
			this.textBoxDoxWin32Bin.ReadOnly = false;
			this.buttonDoxyBinWin32Browse.Enabled = true;
			user.Default.doxygenVersion = "Win32";
			user.Default.Save();
		}

		/// <summary>
		/// Action taken when clicking on the Cygwin Doxygen version radio button.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void RadioButtonDoxCygwin_Click(object sender, EventArgs e)
		{
			// enable cygwin control
			this.textBoxDoxCygwinBin.ReadOnly = false;
			this.buttonDoxyBinCygwinBrowse.Enabled = true;

			// disable win32 control
			this.textBoxDoxWin32Bin.ReadOnly = true;
			this.buttonDoxyBinWin32Browse.Enabled = false;
			user.Default.doxygenVersion = "Cygwin";
			user.Default.Save();
		}

		/// <summary>
		/// Action taken when the Notepad++ radiobutton is checked.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void RadioButtonNotepadPP_CheckedChanged(object sender, EventArgs e)
		{
			if (this.radioButtonNotepadPP.Checked)
			{
				user.Default.editor = "Notepad++";
				user.Default.Save();
			}
		}

		/// <summary>
		/// Action taken when the SourceInsight radiobutton is checked.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void RadioButtonSourceInsight_CheckedChanged(object sender, EventArgs e)
		{
			if (this.radioButtonSourceInsight.Checked)
			{
				user.Default.editor = "SourceInsight3";
				user.Default.Save();
			}
		}

		/// <summary>
		/// Action taken when the TextPad radiobutton is checked.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void RadioButtonTextpad_CheckedChanged(object sender, EventArgs e)
		{
			if (this.radioButtonTextpad.Checked)
			{
				user.Default.editor = "TextPad";
				user.Default.Save();
			}
		}

		/// <summary>
		/// Action taken when the Win32 Doxygen version textbox text changes.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void TextBoxDoxWin32Bin_TextChanged(object sender, EventArgs e)
		{
			user.Default.doxygenWinBin = this.textBoxDoxWin32Bin.Text;
			user.Default.Save();
		}

		/// <summary>
		/// Action taken when the Cygwin Doxygen version textbox text changes.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void TextBoxDoxCygwinBin_TextChanged(object sender, EventArgs e)
		{
			user.Default.doxygenCygBin = this.textBoxDoxCygwinBin.Text;
			user.Default.Save();
		}

		/// <summary>
		/// Action taken when clicking on the Win32 Doxygen version browse button.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void ButtonDoxyBinWin32Browse_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog chosenDoxyBinDir = new FolderBrowserDialog();
			chosenDoxyBinDir.RootFolder = System.Environment.SpecialFolder.MyComputer;
			chosenDoxyBinDir.Description = "Please select where the doxygen binary is located:";

			if (chosenDoxyBinDir.ShowDialog() == DialogResult.OK)
			{
				////this.Trace("The directory "+ chosenDoxyBinDir.SelectedPath +" has been selected");
			}

			try
			{
				this.textBoxDoxWin32Bin.Text = chosenDoxyBinDir.SelectedPath + "\\doxygen.exe";
			}
			catch (System.ArgumentException exception)
			{
				InfoForm infoBox = new InfoForm(exception.Message, "Exception occured");
				infoBox.Show();
			}
		}

		/// <summary>
		/// Action taken when clicking on the Cygwin Doxygen version browse button.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void ButtonDoxyBinCygwinBrowse_Click(object sender, EventArgs e)
		{
			FolderBrowserDialog chosenDoxyBinDir = new FolderBrowserDialog();
			chosenDoxyBinDir.RootFolder = System.Environment.SpecialFolder.MyComputer;
			chosenDoxyBinDir.Description = "Please select where the doxygen binary is located:";

			if (chosenDoxyBinDir.ShowDialog() == DialogResult.OK)
			{
				////this.Trace("The directory "+ chosenDoxyBinDir.SelectedPath +" has been selected");
			}

			try
			{
				this.textBoxDoxCygwinBin.Text = chosenDoxyBinDir.SelectedPath + "\\doxygen.exe";
			}
			catch (System.ArgumentException exception)
			{
				InfoForm infoBox = new InfoForm(exception.Message, "Exception occured");
				infoBox.Show();
			}
		}

		/// <summary>
		/// Action taken when clicking on the Test button.
		/// </summary>
		/// <param name="sender">Event sender.</param>
		/// <param name="e">Event arguments.</param>
		private void TestButton_Click(object sender, EventArgs e)
		{
			string workingDirectory = this.browseBoxDoxygen.Text;

			// ********** BF TEST ************
			// Get the bf project files
			/*
			List<string> bfProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDirectory, "*.dpj");

			//// TODO propose the bf found project files to choose the one to use.

			string[] includeDirsTable = new BFIncludeDirectoriesParser(bfProjFilesList[0]).GetIncludeDirectoriesTable();

			List<string> sourceFilesTable = new BFSourceFilesParser(bfProjFilesList[0]).SourceFilesList;

			string[] projectDefinesTable = new BFProjectDefinesParser(bfProjFilesList[0]).GetProjectDefinesTable();
			*/

			// ********** UV 2 TEST ************
			// Get the uv2 project files
/*			List<string> uvProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDirectory, "*.uv2");

			//// TODO propose the uv2 found project files to choose the one to use.

			string[] includeDirsTable = new UV2IncludeDirectoriesParser(uvProjFilesList[0]).GetIncludeDirectoriesTable();

			List<string> sourceFilesTable = new UV2SourceFilesParser(uvProjFilesList[0]).SourceFilesList;

			string[] projectDefinesTable = new UV2ProjectDefinesParser(uvProjFilesList[0]).GetProjectDefinesTable();

			CcpCreator ccpCreator = new CcpCreator();
			WorkSet currentProjectWorkset = (WorkSet)this.splintToolStripComboBox.SelectedItem;
			ccpCreator.CreateCcpFile(workingDirectory, currentProjectWorkset.RootDir, currentProjectWorkset.ProjectName, sourceFilesTable, projectDefinesTable, includeDirsTable);
*/

			/*
			//********** UV 4 TEST ************
			// Get the uv4 project files
			List<string> uvProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDirectory, "*.uvproj");

			// TODO propose the uv4 found project files to choose the one to use.

			string[] includeDirsTable = new UV4IncludeDirectoriesParser(uvProjFilesList[0]).GetIncludeDirectoriesTable();

			List<string> sourceFilesTable = new UV4SourceFilesParser(uvProjFilesList[0]).SourceFilesList;

			string[] projectDefinesTable = new UV4ProjectDefinesParser(uvProjFilesList[0]).GetProjectDefinesTable();
			*/

			/*
			// ********** TI TEST ************
			// Get the  ti project files
			List<string> tiProjFilesList = RootPathBrowser.GetListOfFilesWithTypeOf(workingDirectory, "*.pjt");

			// TODO propose the uv4 found project files to choose the one to use.
			string[] includeDirsTable = new TIIncludeDirectoriesParser(tiProjFilesList[0]).GetIncludeDirectoriesTable();

			List<string> sourceFilesTable = new TISourceFilesParser(tiProjFilesList[0]).SourceFilesList;

			string[] projectDefinesTable = new TIProjectDefinesParser(tiProjFilesList[0]).GetProjectDefinesTable();
			*/

			// ********** CCPCREATOR TEST ************ 
			/*
			CcpCreator ccpCreator = new CcpCreator();
			WorkSet currentProjectWorkset = (WorkSet)this.splintToolStripComboBox.SelectedItem;
			ccpCreator.CreateCcpFile(workingDirectory, currentProjectWorkset.RootDir, currentProjectWorkset.ProjectName, sourceFilesTable, projectDefinesTable, includeDirsTable);
			*/
		}

		#endregion
	}
}
